<?php

namespace App\Http\Model;

use App\Lib\Snowflake\SnowflakeGenerator;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;


class Gift extends Base
{
    protected $table = 'gift_library';
    protected $specTable = 'gift_spec';
    protected $streamTable = 'gift_stream';
    protected $luckGiftStreamTable = 'luck_gift_stream';
    protected $tableGiftUrl = 'gift_url';
    protected $tableGiftLabel = 'gift_label';
    protected $tableGiftMqRequest = 'gift_request';
    protected $giftLuckPoolTable = 'gift_luck_pool';
    protected $giftLuckLogTable = 'gift_luck_log';
    protected $luckGiftPoolTable = 'luck_gift_pool';
    protected $luckGiftPoolConfigTable = 'luck_gift_pool_config';
    protected $luckGiftWhiteTable = 'luck_gift_white';
    protected $luckGiftLogTable = 'luck_gift_log';
    protected $userGiftStatisticsTable = 'user_gift_statistics';
    protected $giftSendBatchTable = 'gift_send_batch';
    protected $giftBagTable = 'gift_bag';
    protected $hotGiftCardLogTable = 'hot_gift_card_log';
    protected $user = 'user';

    public $timestamps = false;
    private $redis_cache_gift_animate_resources = "CACHE:GIFT:ANIMATE:RESOURCES";
    private $redis_cache_gift = 'CACHE:GIFT';
    protected $redis_cache_time_gift = "CACHE:GIFT:RECKON:TIME:"; //计时礼物缓存
    protected $redis_cache_free_gift = "CACHE:GIFT:FREE:TIME:"; //免费礼物缓存
    protected $redis_cache_gift_union_room_stream = "CACHE:GIFT:UNION:ROOM:STREAM:"; //公会统计礼物缓存
    protected $redis_cache_gift_union_user_stream = "CACHE:GIFT:UNION:USER:STREAM:"; //公会统计礼物缓存

    protected $redis_gift_label = 'CACHE:GIFT:LABEL';

    protected $redis_interact_gift_rule = 'CACHE:GIFT:INTERACT:RULE';
    protected $redis_register_gift = 'CACHE:GIFT:REGISTER';

    protected $giftNamingKey = "CACHE:GIFT:NAMING:"; //礼物冠名 string CACHE:GIFT:NAMING:{gift_id} => {user_id}


    //周星活动配置缓存
    protected $giftstarConfigKey = 'GIFTSTAR:CONFIG:';//string GIFTSTAR:CONFIG:{week} => {json}
    //七夕活动配置缓存
    protected $giftQXstarConfigKey = 'QX:BRIDGEGIFT';//string QX:BRIDGEGIFT => {json}

    //专属礼物赠送特权
    protected $giftExclusiveKey = "CACHE:GIFT:EXCLUSIVE"; //hash CACHE:GIFT:EXCLUSIVE => {gift_id} => {user_id}
    //幸运礼物奖池配置
    protected $giftLuckPoolKey = "CACHE:GIFT:LUCKPOLL:"; //hash CACHE:GIFT:LUCKPOLL:{gift_id} => {json}

    //新幸运礼物奖池缓存
    protected $luckGiftPoolKey = 'LUCKGIFT:POOL';//string LUCKGIFT:POOL => {string}
    //新幸运礼物奖池配置缓存
    protected $luckGiftPoolConfigKey = 'LUCKGIFT:POOLCONFIG:';//string LUCKGIFT:POOLCONFIG:{poolId} => {string}
    //新幸运礼物奖池配置数据缓存
    public $luckGiftPoolDataKey = '{LUCKGIFT:POOLDATA:%s}'; //奖池 {LUCKGIFT:POOLDATA:{poolId}}
    //新幸运礼物用户总消耗钻石数
    protected $userLuckGiftDiamondNumKey = 'LUCKGIFT:USERDIAMONDNUM:';//string LUCKGIFT:USERDIAMONDNUM:{userId} => {num}
    //新幸运礼物用户总消耗钻石数
    protected $userLuckGiftDiamondNumWeekKey = 'LUCKGIFT:USERDIAMONDNUM:';//string LUCKGIFT:USERDIAMONDNUM:{$startWeek.'|'.$endWeek}:{userId} => {num}


    protected $giftConfig;
    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
        $this->giftConfig = new GiftClassificationConfig();
    }

    /**
     * Created at 2022/1/7 10:53
     * @Author <yuxiang.zhu@asiainnovations.net>
     */
    public function classificationConfig()
    {
        return $this->hasOne('App\Http\Model\GiftClassificationConfig', 'gift_id', 'gift_id');
    }

    //礼物列表
    public function getGiftListData($isShow, $page, $page_size, $typeWhere = [])
    {
        if (empty($typeWhere)) {
            $typeWhere = [1];
        }
        $condition = ['is_show' => 1];
        switch ($isShow) {
            case 0:
                // 默认condition条件
                break;
            case 1:
                $condition = [];
                break;
            default:
                break;
        }

        $fields = ['gift_id', 'name', 'image', 'animate_resource', 'animate_resource_md5', 'gift_type', 'price', 'is_show', 'wealth_num'];
        $document = DB::table($this->table)
            ->where($condition)
            ->whereIn('gift_type', $typeWhere)
            ->orderBy('gift_sort', 'asc')
            ->offset(($page) * $page_size)
            ->limit($page_size)
            ->get($fields);
        $result = self::objToArray($document);
        for ($i = 0; $i < count($result); $i++) {
            if (empty($result[$i]['animate_resource'])) {
                $result[$i]['animate_resource'] = null;
            } else {
                $result[$i]['animate_resource'] = getPicDomain() . $result[$i]['animate_resource'];
            }
            $result[$i]['image'] = getPicDomain() . $result[$i]['image'];
        }
        return $result;
    }

    //礼物总数
    public function getGiftTotal()
    {
        $condition = ['is_show' => 1];
        $count = DB::table($this->table)
            ->where($condition)
            ->count('gift_id');
        return $count;
    }

    //获取礼物可选数量
    public function getGiftSpec()
    {
        $condition = ['is_show' => 1];
        $fields = ['spec_num', 'name'];
        $document = DB::table($this->specTable)
            ->where($condition)
            ->orderBy('spec_num', 'asc')
            ->get($fields);
        $result = self::objToArray($document);
        return $result;
    }

    //获取收到的礼物
    public function getObtainGiftList($userId, $page, $page_size)
    {
        $condition = ['user_id' => $userId];
        $document = DB::table($this->streamTable)
            ->where($condition)
            ->orderBy('gift_price', 'desc')
            ->groupBy('gift_id')
            ->select('gift_id', 'gift_name as name', 'gift_price as price', 'gift_image as image', DB::raw('sum(gift_num) as total_num'))
            ->offset(($page) * $page_size)
            ->limit($page_size)
            ->get();

        $result = self::objToArray($document);
        $giftIds = array_column($result,'gift_id');
        $giftData = $this->getGiftByGiftIds($giftIds,['gift_id','image']);
        $giftImageData = array_column($giftData,'image','gift_id');
        for ($i = 0; $i < count($result); $i++) {
            // $result[$i]['image'] = getPicDomain() . $result[$i]['image'];
            $result[$i]['image'] =  isset($giftImageData[$result[$i]['gift_id']])?build_image($giftImageData[$result[$i]['gift_id']]):build_image($result[$i]['image']);
        }

        return $result;
    }

    public function getGiftByGiftIds($giftIds,$field){
        $document = DB::table($this->table)
            ->whereIn('gift_id',$giftIds)
            ->select($field)
            ->get();

        $result = self::objToArray($document);
        return $result;
    }
    //获取收到的礼物总数
    public function getObtainGiftTotal($userId)
    {
        $condition = ['user_id' => $userId];
        $giftTotal = DB::table($this->streamTable)
            ->where($condition)
            ->sum('gift_num');
        return $giftTotal;
    }

    //获取礼物
    public function getGift($condition, $fields)
    {
        $document = DB::table($this->table)->where($condition)->first($fields);
        $result = self::objToArray($document);
        return $result;
    }

    //记录礼物流水
    public function addStream($data)
    {
        if(isset($data['pop_stream'])){
            unset($data['pop_stream']);
            unset($data['color_gift_id']);
            unset($data['pool_id']);
            unset($data['pool_rate_num']);
        }
        
        //增加一个track_id; add by zxiaofee
        // $trackId = SnowflakeGenerator::generateId($this->streamTable);
        // $data['track_id'] = $trackId;
        $result = DB::table($this->streamTable)->insertGetId($data);
        return $result;
    }

    public function addBatchLuckGiftStream($data)
    {
        $result = DB::table($this->luckGiftStreamTable)->insert($data);
        return $result;
    }

    /**
     * 获取房间礼物流水
     * @param $room_id
     * @return mixed
     */
    public function room_stream($room_id, $start_timestamp, $end_timestamp, $page_index, $page_size)
    {
        $document = DB::table($this->streamTable)
            ->where('room_id', '=', $room_id)
            ->where('change_timestamp', '>=', $start_timestamp)
            ->where('change_timestamp', '<=', $end_timestamp)
            ->offset($page_index * $page_size)
            ->limit($page_size)
            ->orderByDesc('change_timestamp')
            ->get(['user_id', 'from_user_id', 'gift_id', 'gift_name', 'gift_price', 'gift_num', 'gift_image', 'gift_animate_resource', 'change_timestamp as timestamp', 'type']);
        $result = self::objToArray($document);

        foreach ($result as $k => $v) {
            $result[$k]['gift_image'] = build_image($result[$k]['gift_image']);
        }
        return $result;
    }


    /**
     * 获取礼物
     * @param $gift_id
     * @return mixed
     */
    public function get_gift($gift_id)
    {
        $data = Redis::HGET($this->redis_cache_gift, $gift_id);
        if (!empty($data)) {
            $cache_data = json_decode($data, true);
            if (!isset($cache_data['classification'])) {
                $cache_data['classification'] = GiftLibrary::CLASSIFICATION_OF_COMMON;
            }

            if ($cache_data['gift_type']) {
                return $cache_data;
            }
        }
        $res = DB::table($this->table)
            ->where(['gift_id' => $gift_id])
            ->first(['gift_id', 'name', 'image', 'animate_resource', 'price', 'gift_type', 'is_special', 'classification', 'wealth_num','hot_num']);
        $result = self::objToArray($res);
        if (empty($result['animate_resource'])) {
            $result['animate_resource'] = null;
        } else {
            $result['animate_resource'] = getPicDomain() . $result['animate_resource'];
        }
        $result['image'] = getPicDomain() . $result['image'];
        $result['config'] = $this->giftConfig->getGiftConfig(intval($gift_id));
        Redis::HSET($this->redis_cache_gift, $gift_id, json_encode($result));
        if (Redis::TTL($this->redis_cache_gift) == -1) {
            Redis::EXPIRE($this->redis_cache_gift, 60 * 5);
        }
        return $result;
    }

    /**
     * 删除礼物缓存
     *
     * Created at 2022/1/6 13:46
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param int $giftId
     */
    public function clearGiftCache(int $giftId)
    {
        Redis::HDEL($this->redis_cache_gift, $giftId);
    }


    /**
     * 获取预加载资源列表
     * @return array
     */
    public function get_animate_resources()
    {
        $data = Redis::GET($this->redis_cache_gift_animate_resources);
        if (!empty($data)) {
            return json_decode($data, true);
        }
        $res = DB::table($this->table)->get(['gift_id', 'animate_resource', 'animate_resource_md5']);
        $result = self::objToArray($res);
        $data = [];
        for ($i = 0; $i < count($result); $i++) {
            if (!empty($result[$i]['animate_resource'])) {
                $result[$i]['animate_resource'] = getPicDomain() . $result[$i]['animate_resource'];
                $data[] = $result[$i];
            }
        }
        Redis::SET($this->redis_cache_gift_animate_resources, json_encode($data));
        Redis::EXPIRE($this->redis_cache_gift_animate_resources, 3600);
        return $data;
    }

    //获取指定礼物的总数
    public function getObtainGiftTotalByGiftId($userId, $giftId)
    {
        $condition = ['user_id' => $userId, 'gift_id' => $giftId];
        $giftTotal = DB::table($this->streamTable)
            ->where($condition)
            ->sum('gift_num');
        return $giftTotal;
    }


    //获取计时礼物可以赠送时间
    public function getGiftReckonTimeCache($userId = 0, $roomId = 0, $giftId = 0)
    {
        return Redis::get($this->redis_cache_time_gift . $userId . ':' . $roomId . ':' . $giftId);
    }

    //设置计时礼物倒计时时间
    public function setGiftRockonTimeCache($userId, $roomId, $giftId, $time = 3)
    {
        $cacheKey = $this->redis_cache_time_gift . $userId . ':' . $roomId . ':' . $giftId;
        $cacheTime = time() + $time * 60;
        return Redis::setex($cacheKey, '86400', $cacheTime);
    }




    //设置免费礼物排行
    public function setFreeGiftCache($user_id, $score)
    {
        $key = $this->redis_cache_free_gift;
        return Redis::zincrby($key, $score, $user_id);
    }


    public function getAll()
    {
        $fields = ['gift_id', 'name', 'image', 'animate_resource', 'animate_resource_md5', 'gift_type', 'price', 'ext_data','gift_label_id'];
        $document = DB::table($this->table)
            ->get($fields);
        $result = self::objToArray($document);
        for ($i = 0; $i < count($result); $i++) {
            if (empty($result[$i]['animate_resource'])) {
                $result[$i]['animate_resource'] = null;
            } else {
                $result[$i]['animate_resource'] = getPicDomain() . $result[$i]['animate_resource'];
            }
            $result[$i]['image'] = getPicDomain() . $result[$i]['image'];
        }
        return $result;
    }

    public function getAllV2()
    {
        $fields = ['gift_id', 'name', 'image', 'animate_resource', 'animate_resource_md5', 'gift_type', 'price', 'ext_data','gift_label_id', 'classification', 'is_show', 'wealth_num'];
        $document = self::query()->from($this->table)->with(['classificationConfig:gift_id,config'])->get($fields);
        $result = self::objToArray($document);
        for ($i = 0; $i < count($result); $i++) {
            if (empty($result[$i]['animate_resource'])) {
                $result[$i]['animate_resource'] = null;
            } else {
                $result[$i]['animate_resource'] = getPicDomain() . $result[$i]['animate_resource'];
            }

            $result[$i]['image'] = getPicDomain() . $result[$i]['image'];
            $config = $result[$i]['classification_config'];
            unset($result[$i]['classification_config']);

        }
        return $result;
    }

    public function getData()
    {
        $fields = ['gift_id', 'name', 'image', 'animate_resource', 'animate_resource_md5', 'gift_type', 'price', 'classification'];
        $document = DB::table($this->table)
            ->get($fields);
        $result = self::objToArray($document);

        // $picDomain = getPicDomain();
        // foreach($result as &$item) {
        //     $item['image'] = $picDomain.$item['image'];
        //     $item['animate_resource'] = $picDomain.$item['animate_resource'];
        // }
        // unset($item);
        return $result;
    }

    public function getReceiveNum($userId)
    {
        $condition = ['user_id' => $userId];
        return DB::table($this->streamTable)
            ->where($condition)
            ->where('change_timestamp', '<', 1577807999)
            ->sum("gift_num");
    }

    public function getSendGiftUserList($userId, $page = 0, $page_size = 1)
    {
        $condition = ['from_user_id' => $userId];
        $document = DB::table($this->streamTable)
            ->where($condition)
            ->where('change_timestamp', '<', 1577807999)
            ->orderBy('total_num', 'desc')
            ->groupBy('user_id')
            ->select('user_id', DB::raw('sum(gift_num) as total_num'))
            ->offset(($page) * $page_size)
            ->limit($page_size)
            ->get();

        return $result = self::objToArray($document);
    }

    //获取收到的礼物-用户年度报告
    public function getObtainGiftListByTime($userId, $page, $page_size)
    {
        $condition = ['user_id' => $userId];
        $document = DB::table($this->streamTable)
            ->where($condition)
            ->where('change_timestamp', '<', 1577807999)
            ->orderBy('gift_price', 'desc')
            ->groupBy('gift_id')
            ->select('gift_id', 'gift_name as name', 'gift_price as price', 'gift_image as image', DB::raw('sum(gift_num) as total_num'))
            ->offset(($page) * $page_size)
            ->limit($page_size)
            ->get();

        $result = self::objToArray($document);
        for ($i = 0; $i < count($result); $i++) {
            $result[$i]['image'] = build_image($result[$i]['image']);
        }

        return $result;
    }

    //生成月统计用户礼物缓存总量
    public function getMonthGiftUserSumCache($startDay, $endDay)
    {
        $res = DB::table($this->streamTable)
            ->where('change_timestamp', '>=', $startDay)
            ->where('change_timestamp', '<=', $endDay)
            ->select('user_id', DB::raw('sum(gift_num * gift_price) as total_num'))
            ->groupBy('user_id')->get();
        $res = $this->objToArray($res);
        $key = $this->redis_cache_gift_union_user_stream . date('Y-m', $startDay);
        foreach ($res as $v) {
            Redis::HSET($key, $v['user_id'], $v['total_num']);
        }
        return true;
    }

    public function getMonthGiftRoomSumCache($startDay, $endDay)
    {
        $res = DB::table($this->streamTable)
            ->where('change_timestamp', '>=', $startDay)
            ->where('change_timestamp', '<=', $endDay)
            ->select('room_id', DB::raw('sum(gift_num * gift_price) as total_num'))
            ->groupBy('room_id')->get();
        $res = $this->objToArray($res);
        $key = $this->redis_cache_gift_union_room_stream . date('Y-m', $startDay);
        foreach ($res as $v) {
            if ($v['room_id'] == 0) continue;
            Redis::HSET($key, $v['room_id'], $v['total_num']);
        }
        return true;
    }

    public function getGiftUrlInfo($gift_id){
        $gift_url = DB::table($this->tableGiftUrl)->where('gift_id' ,$gift_id)->first();
        return $this->objToArray($gift_url);
    }

    public function curdGiftLabel($type ,$data){
        $ret_id = 0;
        switch ($type){
            case 'insert':
                $ret_id = DB::table($this->tableGiftLabel)->insertGetId($data);
                break;
            case 'update':
                $ret_id = $data['id'];
                unset($data['id']);
                DB::table($this->tableGiftLabel)
                    ->where('id' ,$ret_id)
                    ->update($data);
                break;
            case 'del':
                $ret_id = $data['id'];
                DB::table($this->tableGiftLabel)->delete($ret_id);
                Redis::HDEL($this->redis_gift_label ,$ret_id);
        }
        if (!$ret_id){
            return $ret_id;
        }
        $res = DB::table($this->tableGiftLabel)->where('id',$ret_id)->first();
        if($res){
            $res = $this->objToArray($res);
            Redis::HSET($this->redis_gift_label ,$ret_id ,json_encode($res));
        }
        return $ret_id;
    }

    /**获取礼物角标资源
     * @param $label_id
     * @param $key
     * @return mixed|string
     */
    public function getGiftLabelRes($label_id ,$key){
        $res = Redis::HGET($this->redis_gift_label ,$label_id);
        if(!empty($res)){
            $res = json_decode($res ,true);
            return !empty($res[$key]) ? $res[$key] : '';
        }else{
            $res = DB::table($this->tableGiftLabel)->where('id',$label_id)->first();
            $res = $this->objToArray($res);
            if(!empty($res)){
                Redis::HSET($this->redis_gift_label ,$label_id ,json_encode($res));
                return !empty($res[$key]) ? $res[$key] : '';
            }
        }
        return '';
    }


    /**获取互动礼物规则
     * @param int $type
     * @return array|mixed
     */
    public function getInteractRule($type = 0){
        $data = [];
        if(!empty($type)){
            $res = Redis::HGET($this->redis_interact_gift_rule ,$type);
            if(!empty($res)){
                $data = json_decode($res ,true);
            }
        }else{
            $data = Redis::HGETALL($this->redis_interact_gift_rule) ?? [];
        }
        return $data;
    }

    public function setInteractRule($type ,$data){
        Redis::HSET($this->redis_interact_gift_rule ,$type ,json_encode($data));
    }

    /**
     * 格式化礼物信息
     *
     * Created at 2022/1/6 14:17
     * @Author <yuxiang.zhu@asiainnovations.net>
     * @param array $giftInfo 礼物信息
     * @param int $sendGiftNum 发送的礼物数量
     * @param int $sendUserId 发送人user_id
     * @return array
     */
    public function formatGiftInfo(array $giftInfo, int $sendGiftNum = 0, int $sendUserId = 0): array
    {
        if (!isset($giftInfo['gift_id'])) {
            return $giftInfo;
        }

        $giftInfo['gift_id'] = intval($giftInfo['gift_id']);
        $config = $giftInfo['config'] ?? [];
        if (!$config) {
            $config = $this->giftConfig->getGiftConfig($giftInfo['gift_id']);
        }

        if (!isset($giftInfo['classification'])) {
            $giftInfo['classification'] = GiftLibrary::CLASSIFICATION_OF_COMMON;
        }

        $giftInfo['config'] = $config ? json_decode($config, true) : [];
        foreach ($giftInfo['config'] as &$value) {
            if (isset($value['num'])) {
                $value['num'] = intval($value['num']);
            }

            if (isset($value['level'])) {
                $value['level'] = intval($value['level']) == 0 ? $value['level'] : intval($value['level']);
            }

            if (isset($value['min_value'])) {
                $value['min_value'] = intval($value['min_value']);
            }

            if (isset($value['rank_id'])) {
                $value['rank_id'] = intval($value['rank_id']);
            }

            if (isset($value['img'])) {
                $value['img'] = getFullImageUrl($value['img']);
            }

            if (isset($value['resource'])) {
                $value['resource'] = getFullImageUrl($value['resource']);
            }

            unset($value['fileList'], $value['resourceList']);
        }

        return $giftInfo;
    }

    public function setGiftNaming($userId, $giftId, $day)
    {
        $expire = 86400 * $day;
        $key = $this->giftNamingKey.$giftId;
        Redis::SETEX($key, $expire, $userId);
        return true;
    }

    public function getGiftNaming($giftId)
    {
        $key = $this->giftNamingKey.$giftId;
        $userId = Redis::GET($key);
        return $userId;
    }

    public function getGiftstarConfig($giftId)
    {
        $time = time();
        $num = date("N", $time);
        $startTime = date("Y-m-d", $time-86400*($num-1));
        $overTime = date("Y-m-d", (strtotime($startTime)+86400*6));
        $week = $startTime."|".$overTime;

        $cacheKey = $this->giftstarConfigKey.$week;
        $cacheValue = Redis::get($cacheKey);
        if ($cacheValue) {
            $data = json_decode($cacheValue, true);
            $data['giftIds'] = [];
            if(!empty($data['gift1'])) $data['giftIds'][] = $data['gift1'];
            if(!empty($data['gift2'])) $data['giftIds'][] = $data['gift2'];
            if(!empty($data['gift3'])) $data['giftIds'][] = $data['gift3'];
            if(in_array($giftId, $data['giftIds'])) {
                return 1;
            }
        }
        return 0;
    }

    /**
     * 获取七夕获取期间的礼物信息
     */
    public function getQxGiftstarConfig($giftId)
    {
        $cacheKey = $this->giftQXstarConfigKey;
        $cacheValue = Redis::get($cacheKey);
        if ($cacheValue) {
            $data = json_decode($cacheValue, true);
            $data['giftIds'] = array_column($data,'gift_id');
            if(in_array($giftId, $data['giftIds'])) {
                return 1;
            }
        }
        return 0;
        
    }

    public function getGiftExclusive($list, $userId)
    {
        $time = time();
        $hasList = Redis::HVALS($this->giftExclusiveKey);
        $result = [];
        foreach($list as $key=>$val) {
            $val['right_roll_msg'] = '';
            if($val['goods_id'] == 25) {
                $flag = 0;
                if(!empty($hasList)) {
                    foreach($hasList as $item) {
                        $item = json_decode($item, true);
                        //是不是这个用户
                        if($userId == $item['user_id']) {
                            //是否到期
                            if($time < $item['time_limit']) {
                                $flag = 1;
                            }
                        }
                    }
                }
                if($flag) {
                    $val['right_roll_msg'] = '周星专属礼物';
                    $result[$key] = $val;
                }
            }else{
                $result[$key] = $val;
            }
        }

        return $result;
    }

    //礼物抵扣券处理
    public function getGiftDeduct($list, $userId)
    {
        $result = [];
        //所有礼物抵扣券
        $giftMap = [];
        $giftList = DB::table($this->table)->where('gift_type', 9)->get();
        $giftList = objToArray($giftList);
        if(!empty($giftList)) {
            foreach($giftList as $val) {
                $val['ext_data'] = empty($val['ext_data']) ? [] : json_decode($val['ext_data'], true);
                if(!empty($val['ext_data']) && !empty($val['ext_data']['to_gift_id'])) {
                    $giftMap[$val['ext_data']['to_gift_id']] = $val;
                }
            }
        }

        foreach($list as $key=>$val) {
            if(isset($giftMap[$val['goods_id']])) {
                //库存
                $giftBagInfo = DB::table($this->giftBagTable)->where('user_id', $userId)->where('gift_id', $giftMap[$val['goods_id']]['gift_id'])->first();
                $giftBagInfo = objToArray($giftBagInfo);

                $val['deduct_info']['gift_id'] = (int) $giftMap[$val['goods_id']]['gift_id'];
                $val['deduct_info']['gift_name'] = (string) $giftMap[$val['goods_id']]['name'];
                $val['deduct_info']['gift_price'] = (int) $giftMap[$val['goods_id']]['price'];
                $val['deduct_info']['gift_num'] = empty($giftBagInfo['avail']) ? 0 : $giftBagInfo['avail'];
            }
            $result[$key] = $val;
        }

        return $result;
    }

    //获取用户拥有的礼物抵扣券
    public function getGiftDeductByUserId($userId)
    {
        //所有礼物抵扣券
        $giftMap = [];
        $giftList = DB::table($this->table)->where('gift_type', 9)->get();
        $giftList = objToArray($giftList);
        if(!empty($giftList)) {
            foreach($giftList as $val) {
                $val['ext_data'] = empty($val['ext_data']) ? [] : json_decode($val['ext_data'], true);
                if(!empty($val['ext_data']) && !empty($val['ext_data']['to_gift_id'])) {
                    //库存
                    $giftBagInfo = DB::table($this->giftBagTable)->where('user_id', $userId)->where('gift_id', $val['gift_id'])->first();
                    $giftBagInfo = objToArray($giftBagInfo);

                    $val['gift_num'] = empty($giftBagInfo['avail']) ? 0 : $giftBagInfo['avail'];

                    $giftMap[$val['ext_data']['to_gift_id']] = $val;
                }
            }
        }

        return $giftMap;
    }

    //检查礼物抵扣券是否已配置
    public function checkGiftDeduct($deductGiftId=0, $toGiftId=0)
    {
        //所有礼物抵扣券
        $giftIds = [];
        $giftList = DB::table($this->table)->where('gift_type', 9)->get();
        $giftList = objToArray($giftList);
        if(!empty($giftList)) {
            foreach($giftList as $val) {
                if(!empty($deductGiftId) && $val['gift_id']==$deductGiftId) {
                    continue;
                }
                $val['ext_data'] = empty($val['ext_data']) ? [] : json_decode($val['ext_data'], true);
                if(!empty($val['ext_data']) && !empty($val['ext_data']['to_gift_id'])) {
                    $giftIds[] = $val['ext_data']['to_gift_id'];
                }
            }
        }

        if(!empty($giftIds) && in_array($toGiftId, $giftIds)) {
            return true;
        }

        return false;
    }

    /**
     * 获取礼物幸运礼物奖池配置
     */
    public function getGiftLuckPoolByGiftId($giftId, $cahce=1)
    {
        $key = $this->giftLuckPoolKey.$giftId;
        if($cahce) {
            $list = Redis::get($key);
        }
        if(empty($list)){
            $list = DB::table($this->giftLuckPoolTable)
                ->where('gift_id', $giftId)
                ->get();
            $list = self::objToArray($list);
            if(!empty($list)){
                Redis::setex($key, 3600, json_encode($list));
            }
        }else{
            $list = json_decode($list, true);
        }

        return $list;
    }

    /**
     * 新增礼物幸运礼物奖池配置
     */
    public function insertGiftLuckPool($data){
        $id = DB::table($this->giftLuckPoolTable)->insertGetId($data);

        $cacheKey = $this->giftLuckPoolKey.$data['gift_id'];
        Redis::del($cacheKey);

        return $id;
    }

    /**
     * 更新礼物幸运礼物奖池配置
     */
    public function updateGiftLuckPool($id, $data){
        if(empty($id) || empty($data)) {
            return false;
        }
        $id = DB::table($this->giftLuckPoolTable)->where('id' ,$id)->update($data);

        $cacheKey = $this->giftLuckPoolKey.$data['gift_id'];
        Redis::del($cacheKey);

        return $id;
    }

    /**
     * 删除礼物幸运礼物奖池配置
     */
    public function deleteGiftLuckPool($giftId, $ids){
        if(empty($giftId) || empty($ids)) {
            return false;
        }
        $id = DB::table($this->giftLuckPoolTable)->where('gift_id' ,$giftId)->whereNotIn('id', $ids)->delete();

        $cacheKey = $this->giftLuckPoolKey.$giftId;
        Redis::del($cacheKey);

        return $id;
    }

    //记录幸运礼物流水
    public function addGiftLuckLog($data)
    {
        $result = DB::table($this->giftLuckLogTable)->insert($data);
        return $result;
    }

    /**
     * 获取房间买赠礼物流水
     */
    public function roomStreamSumByTime($roomId, $start_timestamp, $end_timestamp)
    {
        $result = DB::table($this->streamTable)
            ->where('room_id', $roomId)
            // ->where('type', 1)
            ->where('change_timestamp', '>=', $start_timestamp)
            ->where('change_timestamp', '<=', $end_timestamp)
            ->selectRaw('gift_id, gift_price, gift_type, sum(gift_num) as gift_num')
            ->groupBy('gift_id')
            ->get();
        $result = self::objToArray($result);

        return $result;
    }

    /**
     * 获取用户收到的指定用户的首次礼物流水
     */
    public function getGiftStreamFirstFromUserId($fromUserId, $toUserId)
    {
        $result = DB::table($this->streamTable)
            ->where('from_user_id', $fromUserId)
            ->where('user_id', $toUserId)
            ->first();
        $result = self::objToArray($result);

        return $result;
    }

    //新幸运礼物新增奖池
    public function luckGiftAddPool($poolName, $minNum, $maxNum, $giftPrice)
    {
        $data = [];
        $data['pool_name'] = $poolName;
        $data['gift_price'] = $giftPrice;
        $data['min_num'] = $minNum;
        $data['max_num'] = $maxNum;
        $data['status'] = 2;

        $id = DB::table($this->luckGiftPoolTable)->insertGetId($data);

        $cacheKey = $this->luckGiftPoolKey;
        Redis::del($cacheKey);

        return $id;
    }

    /**
     * 获取新幸运礼物奖池
     */
    public function getLuckGiftPool(){
        $key = $this->luckGiftPoolKey;
        $list = Redis::get($key);
        if(empty($list)){
            $list = DB::table($this->luckGiftPoolTable)->get();
            $list = self::objToArray($list);
            if(!empty($list)) {
                Redis::setex($key, 86400, json_encode($list));
            }
        }else{
            $list = json_decode($list, true);
        }

        $list = array_column($list, null, 'id');

        return $list;
    }

    //编辑新幸运礼物奖池
    public function editLuckGiftPool($id, $params)
    {
        $upData = [];
        if(!empty($params['status'])) {
            $upData['status'] = $params['status'];
        }
        if(!empty($params['pool_name'])) {
            $upData['pool_name'] = $params['pool_name'];
        }
        if(!empty($params['min_num'])) {
            $upData['min_num'] = $params['min_num'];
        }
        if(!empty($params['max_num'])) {
            $upData['max_num'] = $params['max_num'];
        }
        if(!empty($params['gift_price'])) {
            $upData['gift_price'] = $params['gift_price'];
        }

        if(empty($upData)) {
            return 0;
        }

        $res = DB::table($this->luckGiftPoolTable)->where('id', $id)->update($upData);

        $cacheKey = $this->luckGiftPoolKey;
        Redis::del($cacheKey);

        return $res;
    }

    //新幸运礼物新增奖池配置
    public function luckGiftAddPoolConfig($poolId, $diamondNum, $dataNum)
    {
        $data = [];
        $data['pool_id'] = $poolId;
        $data['diamond_num'] = $diamondNum;
        $data['data_num'] = $dataNum;

        $id = DB::table($this->luckGiftPoolConfigTable)->insertGetId($data);

        $cacheKey = $this->luckGiftPoolConfigKey.$poolId;
        Redis::del($cacheKey);

        return $id;
    }

    /**
     * 获取新幸运礼物奖池配置根据ID
     */
    public function getLuckGiftAddPoolConfigById($id)
    {
        $result = DB::table($this->luckGiftPoolConfigTable)
            ->where('id', $id)
            ->first();
        $result = self::objToArray($result);

        return $result;
    }

    //编辑新幸运礼物奖池配置
    public function editLuckGiftPoolConfig($poolId, $id, $params)
    {
        $upData = [];
        if(!empty($params['is_delete'])) {
            $upData['is_delete'] = $params['is_delete'];
        }
        if(isset($params['diamond_num'])) {
            $upData['diamond_num'] = $params['diamond_num'];
        }
        if(!empty($params['data_num'])) {
            $upData['data_num'] = $params['data_num'];
        }

        if(empty($upData)) {
            return 0;
        }

        $res = DB::table($this->luckGiftPoolConfigTable)->where('id', $id)->update($upData);

        $cacheKey = $this->luckGiftPoolConfigKey.$poolId;
        Redis::del($cacheKey);

        return $res;
    }

    /**
     * 获取新幸运礼物奖池配置
     */
    public function getLuckGiftPoolConfig($poolId){
        $key = $this->luckGiftPoolConfigKey.$poolId;
        $list = Redis::get($key);
        if(empty($list)){
            $list = DB::table($this->luckGiftPoolConfigTable)->where('pool_id', $poolId)->where('is_delete', 0)->get();
            $list = self::objToArray($list);
            if(!empty($list)) {
                Redis::setex($key, 86400, json_encode($list));
            }
        }else{
            $list = json_decode($list, true);
        }

        return $list;
    }

    /**
     * 初始化新幸运礼物奖池配置数据缓存
     */
    public function makeLuckGiftPoolData($poolId, $data){
        $key = sprintf($this->luckGiftPoolDataKey, $poolId);
        aliasInit($key, $data);
    }

    /**
     * 新幸运礼物奖池配置剩余数量
     */
    public function getLuckGiftPoolData($poolId){
        $result = [];
        $key = sprintf($this->luckGiftPoolDataKey, $poolId);
        $nameKey = $key . ':ALIAS:' . 'KEYNAME';
        $valKey = Redis::GET($nameKey);
        if(!empty($valKey)) {
            if(Redis::EXISTS($valKey)) {
                $list = Redis::LRANGE($valKey, 0, -1);
                if(!empty($list)) {
                    foreach($list as $val) {
                        if(empty($result[$val])) {
                            $result[$val]['id'] = $val;
                            $result[$val]['num'] = 0;
                        }
                        $result[$val]['num'] = $result[$val]['num'] + 1;
                    }
                }
            }
        }
        $result = array_values($result);

        return $result;
    }

    //新增新幸运礼物白名单
    public function luckGiftAddWhite($userId, $diamondNum, $adminId)
    {
        $data = [];
        $data['user_id'] = $userId;
        $data['diamond_num'] = $diamondNum;
        $data['admin_id'] = $adminId;
        $data['status'] = 0;

        $id = DB::table($this->luckGiftWhiteTable)->insertGetId($data);

        return $id;
    }

    //删除新幸运礼物白名单
    public function luckGiftDelWhite($whiteId)
    {
        $id = DB::table($this->luckGiftWhiteTable)->where('id', $whiteId)->update(['is_delete'=>1]);

        return $id;
    }

    /**
     * 新幸运礼物用户总消耗钻石数
     */
    public function getUserLuckGiftDiamondNum($userId, $cache=0)
    {
        $num = 0;
        $cacheKey = $this->userLuckGiftDiamondNumKey.$userId;
        if($cache) {
            $num = Redis::get($cacheKey);
        }
        if(empty($num)) {
            $query = DB::table($this->luckGiftLogTable)
                ->where('user_id', $userId);
            $num = $query->sum('u_diamond_num');
        }
        $num = (int) $num;

        Redis::set($cacheKey, $num);
        Redis::expire($cacheKey, 3600);

        return $num;
    }

    /**
     * 用户指定周期总抽奖记录数
     */
    public function getUserLuckGiftDiamondNumByWeek($userId)
    {
        $startWeek = Carbon::today()->startOfWeek()->toDateString();
        $endWeek = Carbon::today()->endOfWeek()->toDateString();
        $cacheKey = $this->userLuckGiftDiamondNumWeekKey.$startWeek.'|'.$endWeek.':'.$userId;
        $num = Redis::get($cacheKey);
        if(empty($num)) {
            $query = DB::table($this->luckGiftLogTable)
                ->where('created_at', '>=', $startWeek.' 00:00:00')
                ->where('created_at', '<',  $endWeek.' 23:59:59')
                ->where('user_id', $userId);
            $num = $query->sum('u_diamond_num');
        }
        $num = (int) $num;

        Redis::set($cacheKey, $num);
        Redis::expire($cacheKey, 86400);

        return $num;
    }

    /**
     * 新幸运礼物用户白名单
     */
    public function getLuckGiftWhite($userId){
        $list = DB::table($this->luckGiftWhiteTable)
            ->where('user_id', $userId)
            ->where('status', 0)
            ->where('is_delete', 0)
            ->get();
        $list = self::objToArray($list);

        return $list;
    }

    //新幸运礼物自指定奖池抽取
    public function drawLuckGift($poolId)
    {
        $key = sprintf($this->luckGiftPoolDataKey, $poolId);
        $poolConfigId = aliasIndex($key);

        return $poolConfigId;
    }

    //累加新幸运礼物用户总消耗钻石数
    public function incrUserLuckGiftDiamondNum($userId, $num)
    {
        if($num <= 0) {
            return false;
        }
        $cacheKey = $this->userLuckGiftDiamondNumKey.$userId;
        $new = Redis::INCRBY($cacheKey, $num);

        return $new;
    }

    //累加新幸运礼物用户周总消耗钻石数
    public function incrUserLuckGiftDiamondNumByWeek($userId, $num)
    {
        if($num <= 0) {
            return false;
        }
        $startWeek = Carbon::today()->startOfWeek()->toDateString();
        $endWeek = Carbon::today()->endOfWeek()->toDateString();
        $cacheKey = $this->userLuckGiftDiamondNumWeekKey.$startWeek.'|'.$endWeek.':'.$userId;
        $new = Redis::INCRBY($cacheKey, $num);

        return $new;
    }

    //新增新幸运礼物抽奖记录
    public function addLuckGiftDrawLog($data)
    {
        $data['ymd'] = date('Ymd');
        $id = DB::table($this->luckGiftLogTable)->insertGetId($data);

        return $id;
    }

    //更新新幸运礼物白名单
    public function updateLuckGiftWhite($id, $logId)
    {
        $res = DB::table($this->luckGiftWhiteTable)->where('id', $id)->update(['status'=>1, 'log_id'=>$logId]);

        return $res;
    }






    /**
     * 更新用户收礼物统计
     */
    public function updateUserGiftStatistics($userId, $giftId, $num, $fromUserId)
    {
        if($num < 1) {
            return 0;
        }
        $time = date('Y-m-d H:i:s', time());
        try {
            $info = DB::table($this->userGiftStatisticsTable)
                ->where('user_id', $userId)
                ->where('gift_id', $giftId)
                ->first();
            $info = objToArray($info);
            if(empty($info)) {
                $cacheKey = 'updateUserGiftStatistics:'.$userId.':'.$giftId;
                if (!redis_lock($cacheKey, 2)) {
                    return 0;
                }
                $data = [
                    'user_id' => $userId,
                    'gift_id' => $giftId,
                    'gift_num' => $num,
                    'first_time' => $time,
                    'first_user_id' => $fromUserId,
                    'last_time' =>$time,
                    'last_user_id' => $fromUserId,
                ];
                DB::table($this->userGiftStatisticsTable)->insertGetId($data);
                redis_unlock($cacheKey);
            }else{
                $data = [
                    'last_time' =>$time,
                    'last_user_id' => $fromUserId,
                ];
                DB::table($this->userGiftStatisticsTable)->where('id', $info['id'])->update($data);
                DB::table($this->userGiftStatisticsTable)->where('id', $info['id'])->increment('gift_num', $num);
            }
        } catch (\Exception $e) {
            write_log('error_sendGift', 'updateUserGiftStatistics', [$userId, $giftId, $num, $fromUserId, 'msg'=>$e->getMessage(), 'line'=>$e->getLine()]);
            return false;
        }

        return 1;
    }

    /**
     * 用户收到的礼物列表
     */
    public function userReceiveGiftList($userId)
    {
        $list = DB::table($this->userGiftStatisticsTable.' as a')
            ->join($this->table.' as b', 'a.gift_id', '=', 'b.gift_id')
            ->where('a.user_id', $userId)
            ->select(['a.user_id', 'a.gift_id', 'a.gift_num', 'b.name', 'b.image', 'b.price', 'b.is_show'])
            ->orderBy('b.price', 'desc')
            ->get();
        $list = objToArray($list);

        return $list;
    }

    //记录礼物批量赠送
    public function addGiftSendBatch($data)
    {
        $result = DB::table($this->giftSendBatchTable)->insertGetId($data);
        return $result;
    }

    //获取礼物批量赠送记录
    public function getGiftSendBatch($batchId)
    {
        $result = DB::table($this->giftSendBatchTable)->where('id', $batchId)->first();
        $result = self::objToArray($result);
        return $result;
    }

    /**
     * 更新礼物批量赠送记录
     */
    public function updateGiftSendBatch($id, $data){
        if(empty($id) || empty($data)) {
            return false;
        }
        $res = DB::table($this->giftSendBatchTable)->where('id' ,$id)->update($data);

        return $res;
    }
    /**
     * 房间真爱榜
     */
    public function getRoomTrueLoveRank($room_id, $page, $limit){
        $basePrice = 520;
        $compareTime = Carbon::now()->subHours(24);//近24小时
        $offset = $page * $limit;
        $res = DB::table($this->streamTable)
                ->where('room_id',$room_id)
                ->where('gift_price','>=',$basePrice)
                ->where('gift_type','!=',5)
                ->where('change_timestamp','>=',strtotime($compareTime))
                ->orderBy('change_timestamp','DESC')
                ->offset($offset)
                ->limit($limit)
                ->get();
        $res = self::objToArray($res);
        return $res;
    }

    /**
     * 新增热度卡礼物流水记录
     */
    public function insertHotGiftCard($data){
        $res = DB::table($this->hotGiftCardLogTable)->insertGetId($data);
        return $res;
    }

    /**
     * 获取房间送出热度卡记录
     */
    public function getRoomHotNum($openRoomId, $giftId){
        $res = DB::table($this->hotGiftCardLogTable)
                ->selectRaw(DB::raw('SUM(hot_num) as total'))
                ->where('open_room_log_id',$openRoomId)
                ->where('gift_id',$giftId)
                ->first();
        $res = self::objToArray($res);
        return $res;
    }

    /**
     * 更新房间送出热度卡记录
     */
    public function updateHotGiftCardLog($id, $updata){
        $res = DB::table($this->hotGiftCardLogTable)->where('id',$id)->update($updata);
        return $res;
    }
    /**
     * 获取礼物流水
     * @param $room_id
     * @return mixed
     */
    public function getStreamList($limit)
    {
        $document = DB::table($this->streamTable)
            ->whereRaw('gift_price * gift_num >= ?', [999])
            ->limit($limit)
            ->orderByDesc('change_timestamp')
            ->get(['user_id', 'from_user_id', 'gift_id', 'gift_name', 'gift_price', 'gift_num', 'gift_image', 'gift_animate_resource', 'change_timestamp as timestamp', 'type','room_id']);
        $result = self::objToArray($document);
        foreach ($result as $k => $v) {
            $user_name = User::where('user_id',$v['user_id'])->get();
            foreach ($user_name as $item){}
            $result[$k]['user_nickname']=$item['nickname'];
            $portrait=json_decode($item['portrait'], true);
            $result[$k]['user_portrait'] = $portrait[0]??'';
            $result[$k]['user_portrait'] = build_image($result[$k]['user_portrait']);
            $from_user_name = User::where('user_id',$v['from_user_id'])->get();
            foreach ($from_user_name as $item2){}
            $result[$k]['from_user_nickname']=$item2['nickname'];
            $portrait2=json_decode($item2['portrait'], true);
            $result[$k]['from_user_portrait'] = $portrait2[0]??'';
            $result[$k]['from_user_portrait'] = build_image($result[$k]['from_user_portrait']);
            $result[$k]['timestamp']=date('Y-m-d H:i:s',$v['timestamp']);
            $result[$k]['gift_image'] = build_image($result[$k]['gift_image']);
        }
        return $result;
    }

    public function getUntreatedLuckGiftStream($id)
    {
        $document = DB::table($this->luckGiftStreamTable)
            ->where('id', '>', $id)
//            ->orderBy('total_num', 'desc')
//            ->groupBy('from_user_id', 'user_id', 'gift_id', 'room_id')
//            ->select('user_id', DB::raw('sum(gift_num) as total_num'))
            ->get();

        return self::objToArray($document);
    }


}
